﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Red.GameData
{
    /// <summary>
    /// Edition environment for modifying the data objects
    /// Connects data with the reflection
    /// NOTE: currently environment supports hot reloading of the data but it DOES NOT support reloading of the reflection
    /// </summary>
    public class EditorEnvironment
    {
        /// <summary>
        /// Data collection for the edited data
        /// </summary>
        public Raw.DataCollection Data { get; private set; }

        /// <summary>
        /// Reflection setup for the data
        /// </summary>
        public Raw.ReflectionData Reflection { get; private set; }

        /// <summary>
        /// Setup editor environment using specified data and reflection paths
        /// </summary>
        /// <param name="dataRootPath">Absolute path to the disk location when all of the game data is stored (recursive loading)</param>
        /// <param name="reflectionRootPath">Absolute path to the disk location when all of the reflection data is stored (recursive loading)</param>
        /// <param name="log">A generic error/progress reporting interface</param>
        /// <returns>Created and fully functional edition environment or NULL if something failed</returns>
        public static EditorEnvironment Setup(string dataRootPath, string reflectionRootPath, Raw.IGenericFileErrorReporter log)
        {
            /// load reflection (read only)
            var reflection = Raw.ReflectionData.Load(log, reflectionRootPath);
            if ( reflection == null )
                return null;

            // create the data collection (read/write)
            var data = Raw.DataCollection.Create(log, dataRootPath);
            if (data == null)
                return null;

            // create the magical environment
            var ret = new EditorEnvironment(data, reflection);
            return ret;
        }

        /// <summary>
        /// Create new edition context
        /// </summary>
        /// <param name="createSyncGroup">Edition context will require a global sync group for ensuring data conistency. Set to false only if you don't want your data to be refreshed when outside changes occur.</param>
        /// <returns></returns>
        public EditorContext CreateContext(bool createSyncGroup = true)
        {
            return new EditorContext(Data, Reflection, createSyncGroup);
        }

        /// <summary>
        /// Private object initializer
        /// </summary>
        private EditorEnvironment(Raw.DataCollection data, Raw.ReflectionData reflection)
        {
            Data = data;
            Reflection = reflection;
        }
    }
}
